package com.lighting.module2;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.NumberFormat;
import java.util.Locale;

@Controller
public class CalController {


    @RequestMapping("/cal")
    @ResponseBody
    @CrossOrigin
    String[] Cal(double p, int m, double yr, int type) {
        Check(p, m, yr, type);
        if (type == 0)//等额本息
        {
            return cal0(p, m, yr);
        } else//等额本金
        {
            return cal1(p, m, yr);
        }
    }

    @RequestMapping("/details")
    @ResponseBody
    @CrossOrigin
    String[][] ShowDetails(double p, int m, double yr, int type) {
        Check(p, m, yr, type);
        if (type == 0) {
            return details0(p, m, yr);
        } else {
            return details1(p, m, yr);
        }
    }

    /**
     * 对用户输入的参数做检查
     * @param p 本金
     * @param m 月份
     * @param yr   年利率
     * @param type 还款类型
     */
    static void Check(double p, int m, double yr, int type) {
        if (p <= 0) {
            throw new IllegalArgumentException("本金必须>0");
        }
        if (m < 1 || m > 360) {
            throw new IllegalArgumentException("贷款月份范围必须在1-360之间");
        }
        if (yr < 1 || yr > 36) {
            throw new IllegalArgumentException("年利率范围必须在1-36之间");
        }
        if (type != 0 && type != 1) {
            throw new IllegalArgumentException("不支持的还款类型");
        }
    }

    /**
     * 以等额本息法 显示详情
     *
     * @param p  本金
     * @param m  月份
     * @param yr 年利率
     * @return 字符串2维数组 [0]月数 [1]各项详情
     */
    private static String[][] details0(double p, int m, double yr) {
        //【2维数组】
        //String[][] 变量名 = new String[外层长度][内层长度]
        String[][] a2 = new String[m][];

        double mr = yr / 12.0 / 100.0;        //mr为月利率
        double pow = Math.pow(1 + mr, m);
        double payment = p * mr * pow / (pow - 1); //月供

        for (int i = 0; i < m; i++) {
            double payInterest = p * mr;                  //偿还利息
            double payPrincipal = payment - payInterest;  //偿还本金
            p = p - payPrincipal;                         //剩余本金

            String[] row = new String[]{                  //一行的数据
                    (i + 1) + "",
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(payment),
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(payPrincipal),
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(payInterest),
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(p)
            };
            a2[i] = row;
        }
        return a2;
    }

    /**
     * 以等额本金法 显示详情
     *
     * @param p  本金
     * @param m  月份
     * @param yr 年利率
     * @return 字符串2维数组 [0]月数 [1]各项详情
     */
    private static String[][] details1(double p, int m, double yr) {
        double payPrincipal = p / m;                     //偿还本金
        double mr = yr / 12.0 / 100.0;
        String[][] a2 = new String[m][];
        for (int i = 0; i < m; i++) {
            double payInterest = p * mr;                 //偿还利息
            p -= payPrincipal;                           //剩余本金
            double payment = payPrincipal + payInterest; //月供
            String[] row = new String[]{
                    (i + 1) + "",
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(payment),
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(payPrincipal),
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(payInterest),
                    NumberFormat.getCurrencyInstance(Locale.CHINA).format(p)
            };
            a2[i] = row;
        }
        return a2;
    }

    /**
     * 以等额本息法 计算还款总额和总利息
     *
     * @param p  本金
     * @param m  月份
     * @param yr 年利率
     * @return 字符串数组 [0]还款总额 [1]总利息
     */
    static String[] cal0(double p, int m, double yr) {
        double mr = yr / 12.0 / 100.0;        //mr为月利率
        double pow = Math.pow(1 + mr, m);
        double payment = p * mr * pow / (pow - 1);

        String[] arr = new String[]{
                NumberFormat.getCurrencyInstance(Locale.CHINA).format(payment * m),
                NumberFormat.getCurrencyInstance(Locale.CHINA).format(payment * m - p)
        };
        return arr;
    }

    /**
     * 以等额本金 法计算还款总额和总利息
     *
     * @param p  本金
     * @param m  月份
     * @param yr 年利率
     * @return 字符串数组 [0]还款总额 [1]总利息
     */
    static String[] cal1(double p, int m, double yr) {
        double mr = yr / 12.0 / 100.0;
        double payPrincipal = p / m;      //偿还本金
        double backup = p;                //备份本金
        double payInterestTotal = 0.0;    //总利息

        for (int i = 0; i < m; i++) {
            double payInterest = p * mr;  //偿还利息
            p -= payPrincipal;            //剩余本金
            payInterestTotal += payInterest;
        }
        //[0]还款总额 [1]总利息
        return new String[]{
                NumberFormat.getCurrencyInstance(Locale.CHINA).format(backup + payInterestTotal),
                NumberFormat.getCurrencyInstance(Locale.CHINA).format(payInterestTotal)
        };
    }
}
